package com.shuwen.gcdj.common.util.file;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.shuwen.gcdj.dto.file.ExcelStateDataDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/***
 * 导入excel监听类
 ** Created by ljf
 ** Date:2023/3/14
 */
@Slf4j
@Component
public class ExcelListener <T> extends AnalysisEventListener<T>{

    //private final RedisService redisService;

    private Map<String, Object> param = new HashMap<>();
    //3000条保存一次数据
    private static final int BATCH_COUNT=1000;
    //数据缓存
    private List<T> list = new ArrayList<>(BATCH_COUNT);
    private List<T> failList = new ArrayList<>();
    //mapper
    private SaveInterface<T> saveInterface;
    //错误信息
    List<String> errList = new ArrayList<>();
    //计数器
    int currentRow = 1;

    @Autowired
    private ExcelStateDataDto excelStateDataDto;

    //构造器
    public ExcelListener(SaveInterface<T> saveInterface, ExcelStateDataDto excelStateDataDto) {
        this.saveInterface = saveInterface;
        this.excelStateDataDto = excelStateDataDto;
    }

    @Override
    public void invoke(T data, AnalysisContext analysisContext) {
        Boolean flag = true;
        try {
            currentRow++;
            //通用方法数据校验
            ExcelImportValid.valid(data);
        }catch (Exception e){
            //在easyExcel监听器中抛出业务异常
            flag = false;
            String errorMessage = e.getMessage();
            errorMessage= "第:"+currentRow+"行"+data+"错误信息为："+errorMessage;
            errList.add(errorMessage);
            failList.add(data);
        }
        if (flag){
            //先将数据加到list中
            list.add(data);
            log.info("解析到一条数据：{}",data.toString());
            // 达到BATCH_COUNT了，需要去存储一次数据库，防止数据几万条数据在内存，容易OOM
            if (list.size() >= BATCH_COUNT) {
                saveData();
                // 存储完成清理 list
                list = new ArrayList<>(BATCH_COUNT);
            }
        }
    }

    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
        showList();
        //保留功能
        //redisService.setString("11111", JSONObject.toJSONString(list),20l);
        //saveData();
    }

    /**
     * 加上存储数据库
     */
    public void saveData() {
        log.info("{}条数据，开始存储数据库！", list.size());
        //saveInterface.save(list,param);
        log.info("存储数据库成功！");
    }

    public void showList(){
        excelStateDataDto.setSuccessCount(list.size());
        excelStateDataDto.setErrorCount(failList.size());
        excelStateDataDto.setErrList(errList);
    }

}
